package com.afdor.rws.dtm.core;

import com.afdor.rws.core.extension.ExtensionLoader;
import com.afdor.rws.core.strategy.IdGeneratorStrategy;
import com.afdor.rws.dtm.DistributedTransactionManager;
import com.afdor.rws.dtm.annotation.Transaction;
import com.afdor.rws.dtm.config.DtmConfig;
import com.afdor.rws.dtm.entities.DistributedTransactionDefinition;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 分布式事务管理器默认实现
 *
 * @author 悭梵
 * @date Created in 2019-01-03 16:00
 */
public class DefaultDistributedTransactionManagerImpl implements DistributedTransactionManager {

    @Getter
    @Setter
    private DtmConfig config;

    private ConcurrentMap<String, DistributedTransactionDefinition> transactionDefinitionMap = new ConcurrentHashMap<>(256);

    @Override
    public DistributedTransactionDefinition generate(@NonNull Transaction transaction) {
        String transactionId = null;
        do {
            transactionId = generateTransactionId();
        } while (transactionDefinitionMap.containsKey(transactionId));
        // TODO 生成子事物
        transactionDefinitionMap.putIfAbsent(transactionId, null);
        return transactionDefinitionMap.get(transactionId);
    }

    @Override
    public DistributedTransactionDefinition generate(@NonNull Transaction transaction, @NonNull DistributedTransactionDefinition definition) {
        return null;
    }

    @Override
    public void commit(@NonNull String transactionId) {
        commit(transactionDefinitionMap.get(transactionId));
    }

    @Override
    public void commit(@NonNull DistributedTransactionDefinition definition) {

    }

    @Override
    public void rollback(@NonNull String transactionId) {
        rollback(transactionDefinitionMap.get(transactionId));
    }

    @Override
    public void rollback(@NonNull DistributedTransactionDefinition definition) {

    }

    protected String generateTransactionId() {
        return String.valueOf(
                ExtensionLoader.getInstance(IdGeneratorStrategy.class)
                        .getExtension(config.getTransactionIdGeneratorStrategyName())
                        .generate()
        );
    }
}
